<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->

<html>
<head>
<title>Customizing how Properties are displayed</title>
<link rel="Stylesheet" href="../../../../prose.css" type="text/css" title="NetBeans Open APIs Style">
</head>
  <body>
  <h1>Customizing how Properties are displayed</h1>
<H2><A name="custom_property_editors"> Customizing property editors </a></H2>
The core implementation provides a set of property editors for common types
of properties. These editors implement the <EM> org.openide.explorer.propertysheet.ExPropertyEditor </EM>
interface. It allows passing custom values to the property editor instances.
This can be useful for customizing the property editors appearance.
<P>
You may want to customize the property editor behavior in different situations:

<H3><A name="new_bean"> When creating a new bean </a></H3>
The properties can be passed to BeanInfo. They are propagated through
BeanNode to the property editor. For example if you have a java.io.File property
in your bean you can use this in the BeanInfo:

<PRE>
// assuming you have this line generated by the ide in the BeanInfo class
properties[PROPERTY_testFile] = new PropertyDescriptor ( "testFile", TestBean.class, "getTestFile", "setTestFile" );
// or alternatively if you return your own array of PropertyDescriptors for
// your bean apply it to the appropriate PropertyDescriptor

// you can add a custom parameter to the PropertyDescriptor
properties[PROPERTY_testFile].setValue("files", Boolean.FALSE);
// (the property editor will not allow selecting files)
</PRE>

<H3><A name="new_node"> When creating a new node </a></H3>
You can directly pass the custom parameters to the properties. One 
example is when overriding method createSheet - you can use the property there.
Or anywhere where you have access to the org.openide.nodes.Node.Property 
value of the property edited by the property editor.

<PRE>
    protected Sheet createSheet() {
        Sheet s = Sheet.createDefault();
        try {
            PropertySupport.ReadWrite p = new PropertySupport.ReadWrite (
                    "myDirectory", // NOI18N
                    java.io.File.class,
                    getString ("PROP_directory"),
                    getString ("HINT_directory")
                ) {
                    public Object getValue () {
                        return &lt;get the value from somewhere&gt;
                    }

                    public void setValue (Object o) {
                        &lt;do something with the value&gt;
                    }
                };
            p.setValue("files", Boolean.FALSE); // passing the custom property value here
            s.get (Sheet.PROPERTIES).put(p);
        } catch (Exception ex) {
            ErrorManager.getDefault().notify(ex);
        }
        return s;
    }
</PRE>
<!-- (too old not relevant)
<p class="nonnormative"><a href="http://www.netbeans.org/source/browse/~checkout~/jarpackager/src/org/netbeans/modules/jarpackager/JarDataObject.java"><code>JarDataObject</code></a>
is an example from NetBeans sources, though this module is now obsolete.</p>

<p class="nonnormative"><a href="http://www.netbeans.org/source/browse/~checkout~/core/src/org/netbeans/core/ui/MountIterator.java"><code>MountIterator</code></a>
is an example from NetBeans sources.</p>
-->
<H3><A name="disabling_ok"> When do you want to disable/enable OK when displaying custom property editor </a></H3>
If you provide your own property editor implementation which supplies a GUI custom editor, that
component will be displayed in a separate window with OK and Cancel buttons.
Implement <a href="../propertysheet/ExPropertyEditor.html">ExPropertyEditor</a> on
your PropertyEditor.  In your implementation of ExPropertyEditor.attachEnv(),
cache the instance of <a href="../propertysheet/PropertyEnv.html">PropertyEnv</a>
that is passed to it.  To enable the OK button, call 
<code>env.setState(PropertyEnv.STATE_VALID)</code>.  To disable it, call
<code>env.setState(PropertyEnv.STATE_INVALID)</code>.


<H3><A name="core_editors_custom_parameters"> Custom parameters in core editors </a></H3>
<p>
Following table presents all property editors in core that can be
used with the mechanism of passing named properties. If you pass a
property that is not supported in the editor (or if you pass wrong argument
type) the custom parameter is ignored.
</p>

    <TABLE border="1" summary="custom parameter list">
        <TR>
            <TH> Property type
            </TH>
            <TH> Parameter name
            </TH>
            <TH> Parameter type
            </TH>
            <TH> Description
            </TH>
        </TR>
        <TR> 
            <TD rowspan="5"> java.io.File </TD>
            <TD> directories</TD>
            <TD> Boolean </TD>
            <TD> should directories be selectable as values for the property </TD>
        </TR>
        <TR> 
            <TD> files</TD>
            <TD> Boolean </TD>
            <TD> should files be selectable as values for the property </TD>
        </TR>
        <TR> 
            <TD> filter</TD>
            <TD> javax.swing.filechooser.FileFilter, java.io.FileFilter, java.io.FilenameFilter </TD>
            <TD> the value can be of any of the supported types and represents filter for the file dialog </TD>
        </TR>
        <TR> 
            <TD> currentDir</TD>
            <TD> java.io.File </TD>
            <TD> the dir that should be preselected when displaying the dialog </TD>
        </TR>
        <TR> 
            <TD> baseDir</TD>
            <TD> java.io.File </TD>
            <TD>
                an absolute directory which can be used as a base
                against which relative filenames should be interpreted.
                Incoming relative paths may be resolved against this
                base directory when e.g. opening a file chooser,
                as with the two-argument <CODE>File</CODE> constructors.
                Outgoing paths which can be expressed relative to this
                base directory may be relativized, according to the
                discretion of the implementation; currently
                files selected in the file chooser which are under the
                base directory (including the base directory itself)
                will be relativized, while others will be left
                absolute. The empty abstract pathname
                (<SAMP>new&nbsp;File("")</SAMP>)
                is used to represent the base directory itself.
            </TD>
        </TR>
        <TR> 
            <TD rowspan='4'> java.lang.Object </TD>
            <TD> superClass</TD>
            <TD> java.lang.Class </TD>
            <TD> Should contain superclass that the value in this property is allowed to be</TD>
        </TR>
        <TR> 
            <TD> nullValue</TD>
            <TD> Boolean, String </TD>
            <TD> Either Boolean.TRUE or a String, in such case the string represents human readable name of the null value</TD>
        </TR>
        <TR> 
            <TD> node</TD>
            <TD> org.openide.nodes.Node </TD>
            <TD> A node to display as root of the custom editor </TD>
        </TR>
        <TR> 
            <TD> lookup</TD>
            <TD> org.openide.util.Lookup </TD>
            <TD> A lookup to use to query for results.</TD>
        </TR>
	<TR> 
	    <TD rowspan='4'>java.lang.String </TD>
	    <TD>instructions</TD>
	    <TD>String</TD>
	    <TD>Should contain localized instructions to the user, to be displayed in the
                String custom editor</TD>
        </TR>
        <TR>
            <TD> nullValue</TD>
            <TD> Boolean, String </TD>
            <TD> Either Boolean.TRUE or a String, in such case the string represents human readable name of the null value</TD>
        </TR>
        <TR>
            <TD>oneline</TD>
            <TD>Boolean</TD>
            <TD>Instructs the property editor that the custom editor should present
                a one-line text control (JTextField or equivalent) rather than
                a multi-line text control (JTextArea or equivalent).
            </TD>
        </TR>
        <TR>
	    <TD>suppressCustomEditor</TD>
            <TD>Boolean</TD>
            <TD>Instructs the property editor to suppress the custom editor 
                button on the property sheet.</TD>
        </TR>
        <TR>
          <TD>htmlDisplayValue</TD>
          <TD>String</TD>
          <TD>
            When it is set the property editor will use htmlDisplayValue as a
            string to be shown to the user. Given HTML is interpreted as
            described in 
            <a href="@org-openide-awt@/org/openide/awt/HtmlRenderer.html"><code>HtmlRenderer</code></a>.
            So it gives a possibility to show property values e.g. in red,
            bold, ... font. Be aware that due to the performance reason, the
            given <em>html</em> longer than 511 bytes will not be interpretted
            as html.
            See <a href="https://bz.apache.org/netbeans/show_bug.cgi?id=44152">issue 44152</a> for details.
          </TD>
        </TR>
	<TR> 
	    <TD rowspan='1'>java.lang.String[]</TD>
	    <TD>item.separator</TD>
	    <TD>String</TD>
	    <TD>Contains the separator that is used when composing individual
                items into <code>getAsText</code> value and parse the text
                when doing <code>setAsText</code>. Since version 5.7.
            </TD>
        </TR>
	<TR>
	    <TD rowspan='3'> java.lang.Integer and primitive integer </TD>
            <TD>stringKeys</TD>
            <TD>String[]</TD>
            <TD> Should contain internationalized strings that should be used as tags in
                 a combo box.  Number of elements must be &gt;= 1.  If this hint is 
                 supplied, the hint <code>intKeyValues</code> must also be supplied
            </TD>
        </TR>
        <TR>
            <TD>intValues</TD>
            <TD> int[] </TD>
            <TD> The values the string keys correspond to. Must have the same number
                 of elements as the string array </TD>
        </TR>
        <TR>
            <TD>codeValues</TD>
            <TD> String[] </TD>
            <TD> Values to use in <code>getJavaInitializationString()</code> in place
                 of hardcoding numbers (useful for constants)</TD>
        </TR>
        <TR>
           <TD> java.lang.Boolean and primitive boolean</TD>
           <TD> stringValues </TD>
           <TD> String[] </TD>
           <TD> Should contain an array of two internationalized strings to be used for user
                displayable text for the boolean values, in the order
            false, true - for example, <code>new String[] {"off","on"}</code>.</TD>
        </TR>
    </TABLE>

<H4> Custom parameters that are not tied with particular editor </H4>

<p>
These custom parameters affect the display provided by the core
implementation. They can be used with any property, they are not
bound to one editor.
</p>

    <TABLE border="1" summary="general parameters">
        <TR>
            <TH>
                Affected part
            </TH>
            <TH> Parameter name
            </TH>
            <TH> Parameter type
            </TH>
            <TH> Description
            </TH>
        </TR>

        <TR>
            <TD rowspan='10'>property sheet</TD>
            <TD><code>inplaceEditor</code></TD>
            <TD><code>org.openide.explorer. propertysheet.InplaceEditor</code></TD>
            <TD> Allows a property editor to supply an instance of the
                 <code>InplaceEditor</code> class to be used inline in the property
                 sheet instead of the default inline editor.  Note this
                 effect can be acheived globally for all properties of
                 a given type by writing an <code>ExPropertyEditor</code> implementation
                 that calls <code>PropertyEnv.registerInplaceEditor</code>
                 in its <code>attachEnv()</code> method, and registering that
                 property editor class using one of the mechanisms of 
                 <code>java.beans.PropertyEditorManager</code>.
            </TD>
        </TR>
        
        <TR>
            <TD><code>canEditAsText</code></TD>
            <TD><code>java.lang.Boolean</code></TD>
            <TD> useful especially when passing value <code>Boolean.FALSE</code> - in this
                 case disable the possibility of editing the the value as text
                 but allows <code>getAsText</code> to return non null.  Also used by passing
                 <code>Boolean.TRUE</code> to indicate that a combo-box editor should allow
                 the user to type their own text into the combo box.
            </TD>
        </TR>

        <TR>
            <TD><code>suppressCustomEditor</code></TD>
            <TD><code>java.lang.Boolean</code></TD>
            <TD> indicates that the property sheet/property panel should not
                 display the custom editor button even if the property editor
                 supports one.
            </TD>
        </TR>

        <TR>
            <TD><code>postSetAction</code></TD>
            <TD><code>javax.swing.Action</code></TD>
            <TD> An action that should be run if, and only if, the user updates
                 the value of the property (or reconfirms the existing value by
                 an explicit gesture, such as pressing enter in the property
                 sheet with an editor opened.  This is useful for code which 
                 should, for example, scroll the editor to a specific position
                 when the user sets a value, but must differentiate between the
                 user setting the value and the value of the property being
                 set programmatically.
            </TD>
        </TR>
        <TR>
            <TD><code>initialEditValue</code></TD>
            <TD><code>java.lang.String</code></TD>
            <TD> A value that should be used as the initial value in a property
                 editor when the user first clicks it.  Used, for example, by
                 the form editor to suggest a generated method name for an
                 event handler, but not display one when the properties are 
                 simply painted - it should only appear when the user starts
                 editing.  Applies to string and combo box inline editors.  Note
                 that a <code>Property</code> supplying this should check to ensure it does
                 not already have a value that should be displayed - if the
                 property offers this value, it will always be preferred to the
                 property editor's value.
            </TD>
        </TR>

        <TR>
            <TD><code>longerDisplayName</code></TD>
            <TD><code>java.lang.String</code></TD>
            <TD> title for the property sheet, must be passed to the
                 bean descriptor (or node)
            </TD>
        </TR>
        
		<TR>
            <TD>nodeDescription</TD>
            <TD><code>java.lang.String</code></TD>
            <TD> When it is set the property contains the text to be shown in the description area of the property sheet. Node.getShortDescription() is used when this property is not set.</TD>
        </TR>
        
		<TR>
            <TD>valueIcon</TD>
            <TD><code>javax.swing.Icon</code></TD>
            <TD> An icon to be displayed in front of the property value.</TD>
        </TR>
		
		<TR>
            <TD>nameIcon</TD>
            <TD><code>javax.swing.Icon</code></TD>
            <TD> An icon to be displayed in front of the property label.</TD>
        </TR>
		
		<TR>
            <TD>propertiesHelpID</TD>
            <TD><code>java.lang.String</code></TD>
            <TD> Help ID for the property sheet window. </TD>
        </TR>
		
        <TR>
            <TD rowspan='2'>custom property editor display</TD>
            <TD><code>title</code></TD>
            <TD><code>java.lang.String</code></TD>
            <TD> title of the custom property dialog, must be passed to the
                 component itself; e.g. <code>panel.putClientProperty("title", "New Custom Title")</code>
            </TD>
        </TR>
        <TR>
            <TD><code>helpID</code></TD>
            <TD><code>java.lang.String</code></TD>
            <TD>help ID in the custom property dialog </TD>
        </TR>
    </TABLE>

<h3><a name="other-prop-eds">Other available property editors</a></h3>

NetBeans includes a number of

<a href="@JDK@/java/beans/PropertyEditor.html">property editors</a>

in its default property editor

<a href="@JDK@/java/beans/PropertyEditorManager.html">search path</a>.

Module authors will sometimes want to make use of the fact that
such an editor exists when creating JavaBean-related code; most
commonly, this means that

<a href="@org-openide-nodes@/org/openide/nodes/Node.Property.html#getPropertyEditor--">node properties</a>
<!-- deprecated
and
<a href="@org-openide-options@/org/openide/options/SystemOption.html">system options</a>
-->
may declare a property to be of a certain type without explicitly
specifying a property editor for it, and rely on the search path to
provide a usable property editor so that the UI will function
pleasantly.

<p>These editors are in a private package outside of the
<code>org.openide</code> hierarchy, so module authors should
<em>not</em> attempt to instantiate or otherwise customize them
directly. It is possible that NetBeans may decide to remove some
such editors if that is necessary for some reason; if this happens,
existing module code should not break (as there are no direct
references to the deleted classes), but rather properties of that
type will cease to be conveniently editable by the user (system
options will still be restored from disk correctly, however). If
this happens, the module author will need to provide an appropriate
editor for the module to be fully functional again.</p>

<p>A few of these editors are for classes in the Open API packages;
in such cases, the documentation for the class in question may
mention that there is a property editor available.</p>

<div class="nonnormative">

<p>Also, the
following Java platform classes currently have special NetBeans
property editors which may be used via the default search path:
</p>

<ul>

<li><a href="@JDK@/java/lang/Boolean.html"><code>java.lang.Boolean</code></a>

<li><a href="@JDK@/java/awt/Color.html"><code>java.awt.Color</code></a>

<li><a href="@JDK@/java/awt/Dimension.html"><code>java.awt.Dimension</code></a>

<li><a href="@JDK@/java/awt/Font.html"><code>java.awt.Font</code></a>

<li><a href="@JDK@/java/awt/Insets.html"><code>java.awt.Insets</code></a>

<li><a href="@JDK@/java/lang/Integer.html"><code>java.lang.Integer</code></a>

<li><a href="@JDK@/java/awt/Point.html"><code>java.awt.Point</code></a>

<li><a href="@JDK@/java/awt/Rectangle.html"><code>java.awt.Rectangle</code></a>

<li><a href="@JDK@/java/io/File.html"><code>java.io.File</code></a>

<li><a href="@JDK@/java/lang/Class.html"><code>java.lang.Class</code></a>

<li><a href="@JDK@/java/lang/String.html"><code>java.lang.String</code></a>

<li><a href="@JDK@/java/net/URL.html"><code>java.net.URL</code></a>

<li><a href="@JDK@/java/util/Date.html"><code>java.util.Date</code></a>

<li><a href="@JDK@/java/util/Properties.html"><code>java.util.Properties</code></a>

<li><a href="@JDK@/javax/swing/ListModel.html"><code>javax.swing.ListModel</code></a>

<li><a href="@JDK@/javax/swing/table/TableModel.html"><code>javax.swing.table.TableModel</code></a>

<li>all primitive wrapper types, such as
<a href="@JDK@/java/lang/Integer.html"><code>java.lang.Integer</code></a></li>

</ul>

<p>
Beware that some of these editors may not provide the ability to
edit the full range of values of the corresponding data type, as
they may be specialized for the NetBeans environment.
</p>

</div>

<p>A number of other editors and property editor extensions are
available in the package
<code>org.openide.explorer.propertysheet.editors</code>,
but these are all deprecated; modules are encouraged to
instead rely solely on the default editor search path, and to add needed configuration

<a href="@JDK@/java/beans/FeatureDescriptor.html#setValue-java.lang.String-java.lang.Object-">parameters</a>

to their

<a href="@org-openide-nodes@/org/openide/nodes/Node.Property.html"><code>Node.Property</code></a>s

or

<a href="@JDK@/java/beans/PropertyDescriptor.html"><code>PropertyDescriptor</code></a>s

so as to be accessible from

<a href="../propertysheet/PropertyEnv.html#getFeatureDescriptor--"><code>PropertyEnv</code></a>

as used by

<a href="../propertysheet/ExPropertyEditor.html">smart</a>

property editors.</p>
  
  </body>
</html>
